<?php
namespace app\install\controller;
use think\Request;
use think\Db;
use think\Controller;

class Install extends Controller
{
    public function index()
    {
        if (is_file(PUBLIC_PATH . 'install' . DS .'install.lock')) {
            header('Location: ' . url('@/'));
            exit();
        }
        $data = array();
        $icon_correct='<i class="el-icon-circle-check"></i> ';
        $icon_error='<i class="el-icon-circle-close"></i> ';
        //php版本、操作系统版本
        $data['phpversion'] = @phpversion();
        $data['os'] = PHP_OS;
        //环境检测
        $err = 0;
        if (class_exists('pdo')) {
            $data['pdo'] = $icon_correct . '已开启';
        } else {
            $data['pdo'] = $icon_error . '未开启';
            $err++;
        }
        //扩展检测
        if (extension_loaded('pdo_mysql')) {
            $data['pdo_mysql'] = $icon_correct . '已开启';
        } else {
            $data['pdo_mysql'] =$icon_error . '未开启';
            $err++;
        }
        if (extension_loaded('curl')) {
            $data['curl'] = $icon_correct . '已开启';
        } else {
            $data['curl'] = $icon_error . '未开启';
            $err++;
        }
        if (extension_loaded('mbstring')) {
            $data['mbstring'] = $icon_correct . '已开启';
        } else {
            $data['mbstring'] = $icon_error . '未开启';
            $err++;
        }
        if (extension_loaded('exif')) {
            $data['exif'] = $icon_correct . '已开启';
        } else {
            $data['exif'] = $icon_error . '未开启';
            $err++;
        }
        //设置获取
        if (ini_get('file_uploads')) {
            $data['upload_size'] = $icon_correct . ini_get('upload_max_filesize');
        } else {
            $data['upload_size'] = $icon_error . '禁止上传';
        }
        if (ini_get('allow_url_fopen')) {
            $data['allow_url_fopen'] = $icon_correct . '已开启';
        } else {
            $data['allow_url_fopen'] = $icon_error . '未开启';
            $err++;
        }
        //函数检测
        if (function_exists('file_get_contents')) {
            $data['file_get_contents'] = $icon_correct.'已开启';
        } else {
            $data['file_get_contents'] = $icon_error.'未开启';
            $err++;
        }
        if (function_exists('session_start')) {
            $data['session'] = $icon_correct . '已开启';
        } else {
            $data['session'] = $icon_error . '未开启';
        }
        //检测文件夹属性
        $cache =  ROOT_PATH . 'runtime';
        $install = ROOT_PATH . 'public/install';
        $config = ROOT_PATH . 'app';
        $newChecklist = array();
        if (is_writable($cache)) {
            $newChecklist['cache']['w'] = true;
        } else {
            $newChecklist['cache']['w'] = false;
        }
        if (is_writable($install)) {
            $newChecklist['install']['w'] = true;
        } else {
            $newChecklist['install']['w'] = false;
        }
        if (is_writable($config)) {
            $newChecklist['config']['w'] = true;
        } else {
            $newChecklist['config']['w'] = false;
        }
        $data['checklist'] = $newChecklist;
        $this->assign('data',$data);
        $request = Request::instance();
        $installAddress = $request->domain() . $request->url();
        $this->assign('installAddress',$installAddress);
        return $this->fetch('install@/install');
    }

    public function installPost(Request $request)
    {
        if (is_file(PUBLIC_PATH . 'install' . DS .'install.lock')) {
            exit();
        }
        if (!Request::instance()->isPost()) {
            exit();
        }
        $dbConfig['hostname'] = input('post.dbHost');
        $dbConfig['database'] = input('post.database');
        $dbConfig['username'] = input('post.dbUsername');
        $dbConfig['password'] = input('post.dbPassword');
        $dbConfig['hostport'] = input('post.dbHostport');
        $dbConfig['prefix'] = input('post.dbPrefix');
        $dbConfig['type'] = 'mysql';
        $dbConfig['dsn'] = '';
        $dbConfig['params'] = [];
        $dbConfig['charset'] = 'utf8';
        
        $username = input('post.username');
        $password = input('post.password');
        $rpassword = input('post.rpassword');
        $mdPassword = input('post.mdPassword');
        $salt = input('post.salt');
        $linkKey = input('post.linkKey');
        $settingsData = input('post.settingsData');
        $installAddress = input('post.installAddress');
        $testData = input('post.testData');
        if (!$username) {
            return jsonError('请输入用户名');
        }
        if (!$password) {
            return jsonError('请输入密码');
        }
        if (!$rpassword) {
            return jsonError('请输入重复密码');
        }
        $dsn = "mysql:dbname={$dbConfig['database']};host={$dbConfig['hostname']};port={$dbConfig['hostport']};charset=utf8";
        try {
            $db = new \PDO($dsn, $dbConfig['username'], $dbConfig['password']);
        } catch (\PDOException $e) {
            return jsonError('错误代码:'.$e->getMessage());
        }
        $sql = file_get_contents(PUBLIC_PATH . 'package'. DS . 'data_v_1_0_0.sql');
        $sql = str_replace("\r", "\n", $sql);
        $isInnoDB = false;
        try {
            $con = mysqli_connect($dbConfig['hostname'], $dbConfig['username'], $dbConfig['password'], $dbConfig['database']); 
            $v = $con->server_info;
            if (strpos($v,'5.7') !== false) {
                $isInnoDB = true;
            }
            if (strpos($v,'8.') !== false) {
                $isInnoDB = true;
            }
        } catch (\PDOException $e) {}
        if (!$isInnoDB) {
            $sql = str_replace("InnoDB", "MyISAM", $sql);
        }
        $sql = explode(";\n", $sql);
        foreach ($sql as $item) {
            $item = trim($item);
            if (empty($item)) continue;
            preg_match('/CREATE TABLE `([^ ]*)`/', $item, $matches);
            if ($matches) {
                if(false !== $db->exec($item)){

                } else {
                   return jsonError('数据库安装失败');
                }
            } else {
                $db->exec($item);
            }
        }
        
        $conf = file_get_contents(PUBLIC_PATH . 'package' . DS . 'database.php');
        foreach ($dbConfig as $key => $value) {
            $conf = str_replace("#{$key}#", $value, $conf);
        }
        $install = CONF_PATH;
        if (!is_writable($install)) {
            return jsonError('路径：' . $install . '没有写入权限');
        }
        try {
            $fileStatus = is_file(CONF_PATH. 'database.php');
            if ($fileStatus) {
              	unlink(CONF_PATH. 'database.php');
            }
            file_put_contents(CONF_PATH. 'database.php', $conf);
        } catch (Exception $e) {
            return jsonError('database.php文件写入失败，请检查 app 文件夹是否可写入');
        }
        
        if ($installAddress) {
            Db::connect($dbConfig, false)->name('BaseSettings')->where('key','runUrl')->update(array(
                'val' => $installAddress,
            ));
        }
        Db::connect($dbConfig, false)->name('BaseSettings')->where('key','systemCode')->update(array(
            'val' => msectime() . rand(10,99),
        ));
        if (!$salt) {
        	$salt = create_salt(8);
        }
        if (!$mdPassword) {
        	$mdPassword = create_md5($password,$salt);
        }
        Db::connect($dbConfig, false)->name('BaseAdmin')->insert(array(
        	'uid' => uuid(),
            'username' => $username,
            'password' => $mdPassword,
            'salt' => $salt,
            'reg_time' => time(),
            'terminal' => 'pc',
        ));
        if ($linkKey) {
	        Db::connect($dbConfig, false)->name('BaseKey')->insert(array(
	        	'key' => 'token',
	            'val' => $linkKey,
	        ));
        }
        if ($settingsData) {
        	$settingsData = json_decode($settingsData,true);
        	if ($settingsData) {
        		foreach($settingsData as $key => $val) {
        			Db::connect($dbConfig, false)->name('BaseSettings')->where('key',$key)->update(array(
		                'val' => $val,
		            ));
        		}
        	}
        }
        //初始化数据
        if ($testData) {
	        $jsonFilePath = ROOT_PATH . 'app' . DS . 'install' . DS . 'testData.json';
	        if (is_file($jsonFilePath)) {
	        	$jsonData = file_get_contents($jsonFilePath);
	        	if ($jsonData) {
	        		$dataArray = json_decode($jsonData,true);
	        		foreach ($dataArray as $key => $data) {
	    				Db::connect($dbConfig)->name('ArticlesCategory')->insert([
	    					'title' => $data['category']['title'],
	    					'url_name' => $data['category']['url_name'],
	    					'template' => 'article.html',
				            'detail_template' => 'articleDetail.html',
				            'category_url' => '/<url_name>/',
				            'category_page_url' => '<category_url>index_<page>.html',
				            'detail_url' => '<category_url><id>.html',
				            'status' => 1,
				            'is_page' => 0,
				            'pid' => 0, 
				            'model_id' => 0, 
				            'model_name' => 'article',
						]);
	    				$categoryInfo = Db::connect($dbConfig)->name('ArticlesCategory')->where('url_name',$data['category']['url_name'])->find();
	    				if ($data['article']) {
	    					foreach ($data['article'] as $k => $v) {
	    						$uuid = uuid();
			        			Db::connect($dbConfig)->name('Articles')->insertGetId([
						            'uuid' => $uuid,
						            'cid' => $categoryInfo['id'],
						            'uid' => '',
						            'views' =>  0,
						            'title' =>  $v['title'],
						            'publish_time' => time(),
					            ]);
						        Db::connect($dbConfig)->name('ArticlesContent')->insert(array(
						            'id' => $uuid,
						            'content' => htmlspecialchars($v['content']),
						        ));
	    					}
	    				}
	        		}
	        	}
	        }
        }
        
        
        $install = ROOT_PATH . 'public' . DS . 'install';
        if (!is_writable($install)) {
            return jsonError('路径：/public/install没有写入权限');
        }
        try {
            touch(PUBLIC_PATH . 'install' . DS . 'install.lock');
            file_put_contents(PUBLIC_PATH . 'install' . DS . 'install.lock', '');
        } catch (Exception $e) {
            return jsonError('install.lock文件写入失败，请检查public/install 文件夹是否可写入');
        }
        
        return jsonSuccess('安装完成','');
    }
    
}
